View Javadoc
1   /*
2    * UrlHandler.java
3    *
4    * Created on December 22, 2004, 12:41 PM
5    */
6   
7   package gov.noaa.eds.xapi.generic.handlers;
8   
9   import gov.noaa.eds.xapi.generic.DomHandler;
10  import gov.noaa.eds.xapi.generic.DomHandlerException;
11  import java.io.IOException;
12  import java.io.InputStream;
13  import java.net.MalformedURLException;
14  import java.net.URL;
15  import java.net.URLConnection;
16  import javax.xml.parsers.DocumentBuilder;
17  import javax.xml.parsers.DocumentBuilderFactory;
18  import javax.xml.parsers.ParserConfigurationException;
19  import org.apache.crimson.jaxp.DocumentBuilderFactoryImpl;
20  import org.w3c.dom.Document;
21  import org.xml.sax.SAXException;
22  
23  /***
24   * Handles communication between a URL.
25   *
26   * @version $Id: UrlHandler.java,v 1.2 2004/12/23 23:39:15 mrxtravis Exp $
27   * @author tns
28   */
29  public class UrlHandler implements DomHandler {
30      
31      private URLConnection connection = null;
32      private Document document = null;
33      private long lastModified = 0;
34      private DocumentBuilderFactory factory = new DocumentBuilderFactoryImpl();
35      
36      /***
37       * Holds value of property url.
38       */
39      private URL url;
40      
41      /***
42       * Holds value of property urlString.
43       */
44      private String urlString;
45      
46      /***
47       * Holds value of property millisBetweenChecks.
48       */
49      private long millisBetweenChecks = 0;
50      private long lastCheck = 0;
51      
52      /*** Creates a new instance of UrlHandler */
53      public UrlHandler() {
54      }
55      
56      /***Unsupported
57       *@todo implement this method
58       */
59      public void setResourceAsNode(org.w3c.dom.Node node) {
60          throw new UnsupportedOperationException("URL Handler is read-only.");
61      }
62      
63      /*** Returns the URL as a Document
64       *@return The URL converted into a Document
65       */
66      public org.w3c.dom.Document getResourceAsDocument() throws DomHandlerException {
67          if (url == null){
68              throw new IllegalStateException("url property not set.");
69          }
70          if (this.lastCheck == 0){
71              this.lastCheck = System.currentTimeMillis();
72              load();
73          } else if (this.millisBetweenChecks == 0 ||
74                  this.lastCheck + this.millisBetweenChecks > System.currentTimeMillis()){
75              this.lastCheck = System.currentTimeMillis();
76              try {
77                  URLConnection connection = url.openConnection();
78                  if (connection.getLastModified() > this.lastModified){
79                      load();
80                  }
81              } catch (IOException e){
82                  throw new DomHandlerException(e);
83              }
84          }
85          return this.document;
86      }
87      
88      /*** Try to minimalize calls to the URL*/
89      private synchronized void load() throws DomHandlerException {
90          URLConnection connection = null;
91          InputStream is = null;
92          try {
93              connection = url.openConnection();
94              long connectionModified = connection.getLastModified();
95              if ( connectionModified > this.lastModified){
96                  this.lastModified = connectionModified;
97                  DocumentBuilder builder = factory.newDocumentBuilder();
98                  is = connection.getInputStream();
99                  if (is == null){
100                     throw new NullPointerException("Could not get an input stream for url:" + url.toExternalForm());
101                 }
102                 Document newDoc = builder.parse(is);
103                 this.document = newDoc;
104             }
105         } catch (IOException e){
106             throw new DomHandlerException(e);
107         } catch (SAXException e) {
108             throw new DomHandlerException(e);
109         } catch (ParserConfigurationException e){
110             throw new DomHandlerException(e);
111         } finally {
112             if (is != null){
113                 try {
114                     is.close();
115                 } catch (IOException e){
116                     //nothing can be done
117                 }
118             }
119         }
120     }
121     
122     /***
123      * Getter for property url.
124      * @return Value of property url.
125      */
126     public URL getUrl() {
127         return this.url;
128     }
129     
130     /***
131      * Setter for property url.
132      * @param url New value of property url.
133      */
134     public void setUrl(URL url) {
135         if (this.url != null){
136             throw new IllegalStateException("uri property has already been set.");
137         }
138         if (url == null){
139             throw new NullPointerException("parameter url must not be null");
140         }
141         this.url = url;
142     }
143     
144     /***
145      * Getter for property urlString.
146      * @return Value of property urlString.
147      */
148     public String getUrlString() {
149         return this.url.toExternalForm();
150     }
151     
152     /***
153      * Setter for property urlString.
154      * @param urlString New value of property urlString.
155      */
156     public void setUrlString(String urlString) throws MalformedURLException {
157         
158         URL u = new URL(urlString);
159         this.setUrl(u);
160     }
161     
162     /***
163      * Getter for property timeBetweenChecks.
164      * @return Value of property timeBetweenChecks.
165      */
166     public long getMillisBetweenChecks()  {
167         
168         return this.millisBetweenChecks;
169     }
170     
171     /***
172      * Setter for property timeBetweenChecks.
173      * @param timeBetweenChecks New value of property timeBetweenChecks.
174      */
175     public void setMillisBetweenChecks(long millisBetweenChecks)  {
176         
177         this.millisBetweenChecks = millisBetweenChecks;
178     }
179     
180 }